<?php

操作系统相关信息
    预定义常量
        PHP_OS              当前操作系统
        PHP_VERSION         当前PHP版本
        PHP_EOL             当前环境的换行符
        DIRECTORY_SEPARATOR 当前环境的目录分隔符

    phpinfo         当前PHP环境信息
    php_uname       当前操作系统的信息 字符串保存
    posix_uname     获取操作系统的信息, 数组形式保存

用户信息
{
    posix_getlogin  获取当前登录用户名
    posix_getuid    获取当前登录用户UID
    posix_geteuid   获取当前程序运行权限用户UID
    posix_setuid    改变当前登录用户UID(只能root用户执行)
    posix_seteuid   改变当前执行权限UID(只能root用户执行)
    getmyuid        获取当前PHP脚本所属用户UID
    getmygid        获取当前PHP脚本所属用户组GID
    get_current_user    获取当前PHP脚本所属用户名

    posix_getgid/posix_getegid/posix_setgid/posix_setegid
    同上，只是对用户组ID获取与设置

    posix_getpwnam  根据用户名获取用户所有信息
    posix_getpwuid  根据用户UID获取用户所有信息
    posix_getgrnam  根据组名获取组所有信息
    posix_getgrgid  根据组GID获取组所有信息
}

密码
{
    绝对不要知道用户的密码，知道越少越安全
    约束用户的密码
    绝对不要以邮件或短信发送用户密码
    推荐使用bcrypt算法(最安全)

    能加密就能解密(编码和解码)
    散列算法(md5 sha1 bcrypt script)
        散列算法不能逆向
        相同数据多次散列结束不一样

    数据库对密码保存字段推荐varchar(255)
    crypt       bcrypt散列算法函数

    password_hash               生成哈希值
    password_verify             验证哈希值
    password_needs_rehash       判断哈希值是否符合最新算法

    双重md5: md5(md5("123"))
}

日期时间
{
    设置PHP默认时区
        方法一: 修改php.ini
            date.timezone = 'Asia/Shanghai'
        方法二: 使用函数
            date_default_timezone_set('Asia/Shanghai');
            date_default_timezone_get   获取当前时区

    time            获取UNIX时间戳
    microtime       返回微秒级时间戳
    mktime          将日期转成UNIX时间戳
    strtotime       按指定格式返回UNIX时间戳
        days secounds minutes hours month year week
        +1 days     返回加一天后的时间戳
        +1 week     返回加一周后的时间戳
        -1 days     返回减一天后的时间戳

    date            格式式日期时间输出
    strftime        格式式日期时间输出
    getdate         返回日期时间
    checkdate       检查日期时间有效性

    DateTimeZone    处理时区类

    DateTime        表示日期时间的类
        getOffset   获取相对于1970的偏移天
        getTimestamp    获取时间戳
        format      格式化日期时间
        diff        比较两个日期，返回两日期间隔(年月日)
        add/sub     对日期时间相加减

    DateInterval    处理日期时间的时间跨度类(strtotime)
        构造函数可以传入格式指定时间跨度, 字符串必须以P开头
        P3D     代表3天
        PT5H20M 代表5小时20分钟, 时间必须加前缀T

    DatePeriod      处理日期时间间隔遍历类
}

环境变量
{
    SHELL 提供环境变量给执行程序传递环境信息, 提高访问效率

    获取某些系统环境信息，可以通过环境变量来访问
    给子进程传递某些信息，可以通过环境变量来实现


    $_ENV/$_SERVER  apache/CGI方式传入
    getenv      获取指定环境变量的值
    putenv      设置环境变量的值, 只影响本进程和子进程
}

进程
{
    将可执行程序(文件)加载到内存中
    每个进程都有一个唯一标识符(PID)
    posix_getpid    获取进程PID

    进程编程
        运行其它程序
            pcntl_exec          在当前进程空间执行程序
                程序参数        第二数组参数控制程序的参数
                环境变量        getenv/putenv
                执行权限        posix_setuid
                工作目录        chdir

            以下函数是对pcntl_exec的封装
            system              执行其它程序并且获取程序执行状态
            exec                返回执行命令执行最后一条结果
            shell_exec/``       返回执行命令的结果
            passthru            将执行命令的结果直接写入标准输出

        多段代码同时执行(可以使用线程代替)

        创建进程 pcntl_fork
            子进程完全复制父进程
            子进程会独立虚拟内存空间，所以父子不能直接通讯
            给子进程返回0, 给父进程返回子进程的PID
            posix_getppid   获取父进程的PID
            子进程先结束，父进程没有结束并且对子进程没有操作，子进程为僵尸进程(子进程需要给父进程返回执行状态) (pcntl_wait)
            父进程先结束，子进程变成孤儿进程，父PID会改变为1

            pcntl_waitpid   等待指定子进程结束状态(可以控制阻塞)
            pcntl_wait      等待子进程结束状态(可以控制阻塞)
                pcntl_wexitstatus   返回子进程错误码(0-255)
                pcntl_wifexited     判断子进程是否正常退出
                pcntl_wifsignaled   判断子进程是否被kill
}

==========================================================
作业：
    读取文件中设定日期进行倒计时
    根据用户出生年月计算年龄
    输出程序执行的时间(微秒级)
        $s = microtime();
            ...
        echo microtime() - $s;
    比较两个日期的大小
    计算指定月的工作日有多少天(考虑假期问题)
    编写日历类(cal)


    创建10个进程分段计算1000-5000内的回文数个数

    使两个进程同时运行，不会产生僵尸进程

    实现简单shell程序
        ls -l -t -w -a -s -h -d
        system("ls -l -t -w -a -s -h -d");

        explode();

        if (pcntl_fork() == 0) {
            getenv("PATH");  //获取命令路径
            pcntl_exec();
        }
        pcntl_wait($status);

    实现su命令功能

        posix_getpwnam

        密码验证

        if (pcntl_fork())
        {
            chdir();        //切换到用户家目录
            putenv();
                HOME / USER/ LOGNAME / MAIL / PATH
            posix_initgroups    将某个用户临时加入某个组
            posix_setgid();
            posix_setuid();

            pcntl_exec("");  //执行用户对应的shell程序
        }
        pcntl_wait($status);


vim:ft=php:
